module PlotData where


--Axis - holds all the information on how to create a collage with an axis inside.
--it is extensible, but in the defaultAxis im not using anything extra.
data Axis = Axis { tlc:Dim,
                   brc:Dim,
                   b1:Float,b2:Float,b3:Float,b4:Float,
                   xAxis:[String],
                   yAxis:[String],
                   axisDecimalFun:(Axis->Pos->(Element,Element)),              
                   axisLines:LineStyle,
                   crossHair:Bool,
                   crossHairLines:LineStyle,
                   crossHairValueSpaceFun:(Float->Int)
                 }
            
--Position, used in Graph,Collage and Screen to identify a position
-- A screen position is a position in the screen
-- a Collage position is a position on the collage
-- and finally a graph position is a position on the graph 
type Pos = {px:Float,py:Float}


--Dimension type 
type Dim = {x:Float,y:Float}


----------------------Graph Values --------------------
--An actual position on the graph
type PlotValue = { pos:Pos,desc:String,showDesc:Bool,valuePt:Form}
--This is for one graph line
type GraphVal = {plotValues:[PlotValue],lineStyle:LineStyle}
--Graph is the collection of different graphs to be shown.
type Graph = { graphVals : [GraphVal] }

---------------------- Axis --------------------
--Used internally for now
data AxisType = X_AXIS | Y_AXIS


--Axis - holds all the information on how to create a collage with an axis inside.
{-
   The length of the axis is based on dimension - borders.
   There are two borders, one for the rhs border and lhs border of the collage.

        <-------------------------------------------->
                         collSize
     (collTopX,collTopY)
       *-----------------------------------------------
       |   B4                                         |
       |  |\grphYEnd                                  |
       |  |                   *(0,0)                  |
       .  .                                           |
       .  . grphStart                       grphXEnd  |
       .B1|/_____________________X________________\ B2|
       |___B3_________________________________________|
                                                     (collX,collY)

  (collX,collY) - The rhs bottom of the collage
  (collTopX,collTopY) - The top of the collage
  B1 - Border between rhs X axis and collage rhs       
  B2 - Border between lhs X axis and collage lhs       
  B3 - Border between bottom Y axis and collage bottom
  B4 - border between top Y axis and collage top

  axisDecimanFun - is a function that creates a decimal value between
                   two values in the graph. For example value 1..2 might
                   have 1,0..1,99 in between. The function gets the argument
                   axis, position in the graph (e.g px=1.5,py=2.9) and 
                   must return two element representing the x decimal and
                   y - decimal
                   
  crossHairValueSpaceFun -- Since the position of the crosshair gets abit
                            messy with all the decimals. This is a way to
                            normalize it (I will change this function to
                            to something better someday). 
 
-}
data Axis = Axis { tlc:Dim, --Top left corner
                   brc:Dim, --bottom right corner
                   b1:Float,b2:Float,b3:Float,b4:Float, --See documentation above
                   xAxis:[String], --Values along the xAxis
                   yAxis:[String], --Values along the yAxis
                   axisDecimalFun:(Axis->Pos->(Element,Element)), -- see doc. above             
                   axisLines:LineStyle, -- linestyle of the axis
                   crossHair:Bool, --Crosshair shown?
                   crossHairLines:LineStyle, --crosshair linestyle
                   crossHairValueSpaceFun:(Float->Int)
                 }


---------------------- Some default values that can be used --------------------
defaultValuePt : Form
defaultValuePt = filled red  <| ngon 4 5.0

otherValuePt : Form
otherValuePt = filled black <| circle 3.0


spaceXAxisValue : Float
spaceXAxisValue = 13.0

spaceYAxisValue : Float
spaceYAxisValue = 13.0



defaultAxis : Axis 
defaultAxis = Axis {tlc={x=0,y=0},
                    brc={x=1000,y=400},
                    b1=20,b2=20,b3=20,b4=20,
                    xAxis = ["Jan","Feb","Mar","April","4","5","6","7","8","9","10"],
                    yAxis = ["0","1","2","3"],
                    axisDecimalFun = defaultAxisDecimalFun,
                    axisLines = solid red,
                    crossHair = True,
                    crossHairLines = dotted blue,
                    crossHairValueSpaceFun = floor
                   }

graphValueTest = [{pos={px=0,py=0} ,desc="Test 0",valuePt=defaultValuePt,showDesc=True},
                  {pos={px=1,py=1} ,desc="Test 1",valuePt=defaultValuePt,showDesc=True},
                  {pos={px=2,py=2} ,desc="Test 2",valuePt=defaultValuePt,showDesc=True},
                  {pos={px=3,py=2} ,desc="Test 3",valuePt=defaultValuePt,showDesc=True},
                  {pos={px=5,py=3} ,desc="Test 4",valuePt=defaultValuePt,showDesc=True},
                  {pos={px=6,py=1} ,desc="Test 5",valuePt=defaultValuePt,showDesc=True}]

grphValueTest = {plotValues=graphValueTest,lineStyle = solid red}

graphValueTest1 = [{pos={px=0,py=0}     ,desc="Test 0",valuePt=otherValuePt,showDesc=True},
                   {pos={px=1,py=1}     ,desc="Test 1.1",valuePt=otherValuePt,showDesc=False},
                   {pos={px=1.2,py=1.3} ,desc="Test 1",valuePt=otherValuePt,showDesc=True},
                   {pos={px=1.8,py=2.4} ,desc="Test 2",valuePt=otherValuePt,showDesc=True},
                   {pos={px=2.0,py=3}   ,desc="Test 3",valuePt=otherValuePt,showDesc=False},
                   {pos={px=3,py=3}     ,desc="Test 4",valuePt=otherValuePt,showDesc=True},
                   {pos={px=8,py=1}     ,desc="Test 5",valuePt=otherValuePt,showDesc=True}]

grphValueTest1 = {plotValues=graphValueTest1,lineStyle = solid blue}

graph = { graphVals = [grphValueTest,grphValueTest1]}

--one decimal function that can be used..
defaultAxisDecimalFun :Axis-> Pos -> (Element,Element)
defaultAxisDecimalFun axis pos = let xPos = round ((pos.px - toFloat (floor pos.px))*100)
                                     yPos = round ((pos.py - toFloat (floor pos.py))*100)
                                 in (plainText (show xPos),plainText (show yPos))
